'use strict';

const path = require('path');
const fse = require('fs-extra');
const pkgDir = require('pkg-dir').sync;
const pathExists = require('path-exists').sync;
const npminstall = require('npminstall');
const { isObject } = require('@jay-cli-dev/utils');
const formatPath = require('@jay-cli-dev/format-path');
const { getDefaultRegistry, getNpmLatestVersion } = require('@jay-cli-dev/get-npm-info');

class Package {
    constructor(options) {
        if (!options) {
            throw new Error('Package类的options参数不能为空！');
        }

        if (!isObject(options)) {
            throw new Error('Package类的options参数必须为对象！');
        }

        // package的目标路径
        this.targetPath = options.targetPath;

        // 缓存package的路径
        this.storeDir = options.storeDir;

        // package的name
        this.packageName = options.packageName;
        
        // package的version
        this.packageVersion = options.packageVersion;

        // pakcage的缓存目录前缀
        this.cacheFilePathPrefix = this.packageName.replace('/', '_');
    }

    // 
    async prepare() {
        // 若缓存路径中无目录，则生成
        if (this.storeDir && !pathExists(this.storeDir)) {
            fse.mkdirpSync(this.storeDir);
        }

        // 获取到命令包的最新版本号
        if (this.packageVersion === 'latest') {
            this.packageVersion = await getNpmLatestVersion(this.packageName);
        }
    }

    get cacheFilePath() {
        // 目标缓存文件路径：_@imooc-cli_init@1.0.1@@imooc-cli/init
        // 当前包名：@imooc-cli 命令：init 包版本号：1.0.1
        return path.resolve(this.storeDir, `_${this.cacheFilePathPrefix}@${this.packageVersion}@${this.packageName}`);
    }

    getSepecificCacheFilePath(packageVersion) {
        return path.resolve(this.storeDir, `_${this.cacheFilePathPrefix}@${packageVersion}@${this.packageName}`);
    }

    // 判断当前package是否存在
    async exists() {
        if (this.storeDir) { // 缓存模式
            await this.prepare();
            return pathExists(this.cacheFilePath);
        } else {
            return pathExists(this.targetPath);
        }
    }

    // 安装package
    install() {
        return npminstall({
            root: this.targetPath,
            storeDir: this.storeDir,
            registry: getDefaultRegistry(),
            pkgs: [{ 
                name: this.packageName,
                version: this.packageVersion 
            }]
        })
    }

    // 更新package
    async update() {
        await this.prepare();

        // 1. 获取最新的npm模块版本号
        const latestPackageVersion = await getNpmLatestVersion(this.packageName);
        // 2. 查询最新版本号对应的路径是否存在
        const latestFilePath = this.getSepecificCacheFilePath(latestPackageVersion);
        // 3. 如果不存在，则直接安装最新版本
        if (!pathExists(latestFilePath)) {
            await npminstall({
                root: this.targetPath,
                storeDir: this.storeDir,
                registry: getDefaultRegistry(),
                pkgs: [{ 
                    name: this.packageName,
                    version: latestPackageVersion 
                }]
            })
            this.packageVersion = latestPackageVersion;
        }
    }

    // 获取本地代码入口文件
    getRootFilePath() {
        function _getRootFile(targetPath) {
            // 1. 获取 package.json 所在目录 - pkg-dir
            const dir = pkgDir(targetPath);
            if (dir) {
                // 2. 读取 package.json - require()
                const pkgFile = require(path.resolve(dir, 'package.json'));
                // 3. 寻找 main/lib - path
                if (pkgFile && (pkgFile.main)) {
                    // 4. 路径的兼容（macOS/windows）
                    return formatPath(path.resolve(dir, pkgFile.main));
                }
            }
            return null
        }
        if (this.storeDir) {
            return _getRootFile(this.cacheFilePath);
        } else {
            return _getRootFile(this.targetPath);
        }
    }
}

module.exports = Package;